# Copyright (c) 2013, 2015 Ruslan Baratov
# All rights reserved.

cmake_minimum_required(VERSION 3.0)
project(Hunter)

include(ExternalProject) # ExternalProject_Add

# Scheme for download and install OpenSSL library

list(APPEND CMAKE_MODULE_PATH "@HUNTER_SELF@/cmake/modules")

include(hunter_dump_cmake_flags)
include(hunter_pick_archiver)
include(hunter_status_debug)
include(hunter_assert_not_empty_string)
include(hunter_user_error)

hunter_status_debug("Scheme: url_sha1_openssl")

# Check preconditions
hunter_assert_not_empty_string("@HUNTER_SELF@")
hunter_assert_not_empty_string("@HUNTER_EP_NAME@")
hunter_assert_not_empty_string("@HUNTER_PACKAGE_URL@")
hunter_assert_not_empty_string("@HUNTER_PACKAGE_SHA1@")
hunter_assert_not_empty_string("@HUNTER_PACKAGE_DOWNLOAD_DIR@")
hunter_assert_not_empty_string("@HUNTER_PACKAGE_SOURCE_DIR@")
hunter_assert_not_empty_string("@HUNTER_PACKAGE_INSTALL_PREFIX@")
hunter_assert_not_empty_string("@HUNTER_PACKAGE_LICENSE_DIR@")
hunter_assert_not_empty_string("@HUNTER_GLOBAL_SCRIPT_DIR@")
hunter_assert_not_empty_string("@HUNTER_TLS_VERIFY@")

if(ANDROID OR RASPBERRY_PI OR OPENWRT)
  # -> CMAKE_AR
  # -> CMAKE_RANLIB
  hunter_pick_archiver()

  # Using the ./config script is currently broken with -no* CFLAGS on ALL versions
  # * https://github.com/openssl/openssl/issues/3493
  # * https://github.com/openssl/openssl/blob/OpenSSL_1_1_0-stable/Configure#L560
  # * https://wiki.openssl.org/index.php/Compilation_and_Installation#Configure_.26_Config
  set(configure_command AR=${CMAKE_AR} RANLIB=${CMAKE_RANLIB} "./Configure")
elseif(MINGW)
  if(HUNTER_OPENSSL_MINGW64)
    set(configure_command "./Configure" mingw64)
  else()
    set(configure_command "./Configure" mingw)
  endif()
else()
  set(configure_command "./config")
endif()

set(skip_includes SKIP_INCLUDES)
if(ANDROID)
  set(skip_includes "")
endif()

hunter_dump_cmake_flags(${skip_includes})
# -> CMAKE_CXX_FLAGS
# -> CMAKE_C_FLAGS

if(ANDROID)
  string(COMPARE EQUAL "${CMAKE_ANDROID_ARCH}" "" _has_old_cmake)
  string(COMPARE EQUAL "${ANDROID_ARCH_NAME}" "" _has_unexpected_toolchain)
  if (NOT _has_old_cmake)
    set(ANDROID_SSL_ARCH "${CMAKE_ANDROID_ARCH}")
  elseif(NOT _has_unexpected_toolchain)
    set(ANDROID_SSL_ARCH "${ANDROID_ARCH_NAME}")
  else()
    hunter_user_error("Could not find android architecture. Please set ANDROID_ARCH_NAME in your toolchain or use CMake 3.7+")
  endif()

  # Building OpenSSL with Android:
  # * https://wiki.openssl.org/index.php/Android#Build_the_OpenSSL_Library
  # Set environment variables similar to 'setenv-android.sh' script:
  # * https://wiki.openssl.org/index.php/Android#Adjust_the_Cross-Compile_Script

  # Using documented method (./config script):
  #set(configure_command
      # Ignored. Prevents ./config from checking host uname
  #   RELEASE=2.6.37
  #   SYSTEM=android
  #   ARCH=${CMAKE_ANDROID_ARCH}
  #   ${configure_command})

  # Using android-* targets is currently broken for Clang on ALL versions
  # * https://github.com/openssl/openssl/pull/2229
  # The ./config script only detects Android x86 and armv7 targets anyway.
  # * https://github.com/openssl/openssl/issues/2490
  if (ANDROID_SSL_ARCH MATCHES "mips64|arm64|x86_64")
    set(configure_opts "linux-generic64")
  else()
    set(configure_opts "linux-generic32")
  endif()

  # On Android '--sysroot' differs for compile and linker.
  # With the '-l*' trick we can pass needed '--sysroot' to linker but not to
  # compiler.
  #
  # Tested:
  # * android-ndk-r16b-api-21-armeabi-v7a-neon-clang-libcxx
  # * android-ndk-r17-api-24-arm64-v8a-clang-libcxx14
  # * android-ndk-r18-api-24-arm64-v8a-clang-libcxx14
  list(APPEND configure_opts "-latomic ${CMAKE_EXE_LINKER_FLAGS}")
elseif(RASPBERRY_PI)
  set(configure_opts "linux-generic32")
elseif(OPENWRT)
  set(configure_opts "linux-generic32" "no-async")
endif()

string(REGEX REPLACE "^ " "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")

# Pass C compiler through
set(configure_command
    MACHINE=${CMAKE_SYSTEM_PROCESSOR}
    CC=${CMAKE_C_COMPILER}
    ${configure_command})

# Pass C flags through
set(configure_opts ${configure_opts} ${CMAKE_C_FLAGS})

set(
    configure_command
    . "@HUNTER_GLOBAL_SCRIPT_DIR@/clear-all.sh" && "${configure_command}"
)
set(build_command . "@HUNTER_GLOBAL_SCRIPT_DIR@/clear-all.sh" && make)

if (BUILD_SHARED_LIBS)
  set(shared_flag shared)
else()
  set(shared_flag no-shared)
endif()

set(configure_opts ${configure_opts} threads ${shared_flag})

hunter_status_debug("Configure command: ${configure_command}")
hunter_status_debug("Configure options: ${configure_opts}")

ExternalProject_Add(
    "@HUNTER_EP_NAME@"
    URL
    @HUNTER_PACKAGE_URL@
    URL_HASH
    SHA1=@HUNTER_PACKAGE_SHA1@
    DOWNLOAD_DIR
    "@HUNTER_PACKAGE_DOWNLOAD_DIR@"
    TLS_VERIFY
    "@HUNTER_TLS_VERIFY@"
    SOURCE_DIR
    "@HUNTER_PACKAGE_SOURCE_DIR@"
    INSTALL_DIR
    "@HUNTER_PACKAGE_INSTALL_PREFIX@"
        # not used, just avoid creating Install/<name> empty directory
    CONFIGURE_COMMAND
    ${configure_command}
    ${configure_opts}
    "--prefix=@HUNTER_PACKAGE_INSTALL_PREFIX@"
    BUILD_COMMAND
    ${build_command}
    BUILD_IN_SOURCE
    1
    INSTALL_COMMAND
    make install_sw
    # Install without documentation
    # * https://github.com/openssl/openssl/issues/57
    COMMAND # Copy license files
    "@CMAKE_COMMAND@"
    "-C@HUNTER_ARGS_FILE@" # for 'HUNTER_INSTALL_LICENSE_FILES'
    "-Dsrcdir=@HUNTER_PACKAGE_SOURCE_DIR@"
    "-Ddstdir=@HUNTER_PACKAGE_LICENSE_DIR@"
    -P
    "@HUNTER_SELF@/scripts/try-copy-license.cmake"
)
